#include <iostream>
#include <vector>
#include "types.h"
#include "help.h"
extern std::vector <user> Subjects;
extern std::vector <file> Objects;
extern std::vector <SOA> ACM;

int verify(user &u)
{
    int found = 0;
    std::vector <user>::iterator it;
    for (it = Subjects.begin(); it != Subjects.end(); it++)
    {
        if (it->password == u.password && it->name == u.name) {
            found = 1;
            fprintf(stdout, CYAN "[init] Valid user and password\n" NONE);
            return 1;
        }
    }
    if(!found)
    {
        fprintf(stdout, RED "[error] Invalid user and password\n" NONE);
        return 0;
    }
    return 0;
}
void test_central()
{
    int level = 0;  // root(0) or normal(1)
    int flag = 0;   // central(0) or distributed(1)
    user u;
    u.name = "admin";
    u.password = "root";
    if(!verify(u))
    {
        std::cout << "Verify failed" << std::endl;
    }
    class current_user cu(level, flag, u);
    std::string s1, s2;

    s1 = "lwy"; s2 = "123456";
    cu.create_subject(s1, s2);
    s1 = "lyq"; s2 = "123456";
    cu.create_subject(s1, s2);
    s1 = "lqk"; s2 = "123456";
    cu.create_subject(s1, s2);
    s1 = "yxm"; s2 = "123456";
    cu.create_subject(s1, s2);

    s1 = "f1"; s2 = "newfile f1";
    cu.create_object(s1, s2);
    s1 = "f2"; s2 = "newfile f2";
    cu.create_object(s1, s2);
    s1 = "f3"; s2 = "newfile f3";
    cu.create_object(s1, s2);
    
    s1 = "f2"; s2 = "revise f2";
    cu.write_object(s1, s2);

    s1 = "f3";
    cu.delete_object(s1);
    
    s1 = "lwy";
    cu.delete_subject(s1);

    s1 = "lyq"; s2 = "f1";
    cu.transfer_right(OWN, s1, s2); // THIS SHOULD BE IGNORE
    cu.transfer_right(READ, s1, s2);

    u.name = "lyq";
    u.password = "123456";
    class current_user cu2(level, flag, u);   
    
    s1 = "f1"; s2 = "i can't wirte!";
    cu2.write_object(s1, s2); // THIS SHOULD BE IGNORE

    s1 = "lqk"; s2 = "f1";
    cu2.transfer_right(READ, s1, s2); // THIS SHOULD BE IGNORE

    s1 = "f3"; s2 = "newfile f3";
    cu2.create_object(s1, s2);

    s1 = "lqk"; s2 = "f3";
    cu2.transfer_right(READ, s1, s2); 
    cu2.transfer_right(WRITE, s1, s2); 
    cu2.transfer_right(OWN, s1, s2); // THIS SHOULD BE IGNORE

    u.name = "lqk";
    u.password = "123456";
    class current_user cu3(level, flag, u);   
    
    s1 = "f3"; s2 = "lqk revised";
    cu3.write_object(s1, s2);
    
    print_all();
}
void test_distributed()
{
    int level = 0;  // root(0) or normal(1)
    int flag = 1;   // central(0) or distributed(1)
    user u;
    u.name = "admin";
    u.password = "root";
    if(!verify(u))
    {
        std::cout << "Verify failed" << std::endl;
    }
    class current_user cu(level, flag, u);
    std::string s1, s2;

    s1 = "lwy"; s2 = "123456";
    cu.create_subject(s1, s2);
    s1 = "lyq"; s2 = "123456";
    cu.create_subject(s1, s2);
    s1 = "lqk"; s2 = "123456";
    cu.create_subject(s1, s2);
    s1 = "yxm"; s2 = "123456";
    cu.create_subject(s1, s2);

    s1 = "f1"; s2 = "newfile f1";
    cu.create_object(s1, s2);
    s1 = "f2"; s2 = "newfile f2";
    cu.create_object(s1, s2);
    s1 = "f3"; s2 = "newfile f3";
    cu.create_object(s1, s2);
    
    s1 = "f2"; s2 = "revise f2";
    cu.write_object(s1, s2);

    s1 = "f3";
    cu.delete_object(s1);
    
    s1 = "lwy";
    cu.delete_subject(s1);


    s1 = "lyq";
    s2 = "f1";
    cu.transfer_right(READ, s1, s2);
    cu.transfer_right(OWN, s1, s2);

    s1 = "yxm";
    s2 = "f1";
    cu.transfer_right(READ, s1, s2);

    u.name = "lyq";
    u.password = "123456";
    class current_user cu2(level, flag, u);

    s1 = "lqk";
    s2 = "f1";
    cu2.transfer_right(READ, s1, s2);
    cu2.transfer_right(OWN, s1, s2);

    s1 = "yxm";
    s2 = "f1";
    cu2.transfer_right(READ, s1, s2);

    u.name = "lqk";
    u.password = "123456";
    class current_user cu3(level, flag, u);
    
    s1 = "yxm";
    s2 = "f1";
    cu3.transfer_right(READ, s1, s2);
    
    print_acm();
    
    s1 = "lyq";
    s2 = "f1";
    cu.revoke_right(READ, s1, s2);
    
    print_acm();
}